namespace egret.socketio.engine {

    let err: Packet = { type: "error", data: "parser error" };

    export class Parser {

        public static decodePacket(data: string, utf8decode: boolean): Packet {
            if (data === undefined) {
                return err;
            }

            if (utf8decode) {
                return err;
            }

            let type = Number(data.charAt(0));
            if (!_emPacketType[type]) {
                return err;
            }

            if (data.length > 1) {
                return { type: _emPacketType[type], data: data.substring(1) };
            } else {
                return { type: _emPacketType[type] };
            }
        }

        public static decodePayload(data: string, fn: Function): void {
            if (!data || data.length === 0) {
                return fn(err, 0, 1);
            }
            let length: string = '', n: number, msg: string;
            for (let i = 0, l = data.length; i < l; i++) {
                let chr = data.charAt(i);

                if (':' != chr) {
                    length += chr;
                    continue;
                }

                if (length === '' || (length != (n = Number(length)).toString())) {
                    return fn(err, 0, 1);
                }
                msg = data.substr(i + 1, n);
                if (n != msg.length) {
                    return fn(err, 0, 1);
                }

                if (msg.length) {
                    let packet = this.decodePacket(msg, false);
                    if (err.type === packet.type && err.data === packet.data) {
                        return fn(err, 0, 1);
                    }

                    let ret = fn(packet, i + n, l);
                    if (false === ret)
                        return;
                }

                i += n;
                length = '';
            }

            if (length != '') {
                return fn(err, 0, 1);
            }
        }

        public static encodePacket(packet: Packet, utf8decode: boolean, fn: Function): void {

            let encoded: string = _emPacketType[packet.type].toString();

            if (packet.data) {
                encoded += packet.data;
            }
            fn(encoded);
        }

        public static encodePayload(packets: Packet[], fn: Function) {
            /**
             * TODO: 预留字节编码
             */

            if (packets.length === 0) {
                return fn('0:');
            }

            let result: string = '';
            for (let idx in packets) {
                this.encodePacket(packets[idx], false, (message: string) => {
                    result += this.setLengthHeader(message);
                });
            }

            fn(result);
        }

        private static setLengthHeader(message: string): string {
            return message.length.toString() + ':' + message;
        }
    }
}